package com.ym.b2b.payment.controller.allinPay;

import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.util.HttpURLConnection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.allinpay.ets.client.PaymentResult;
import com.allinpay.ets.client.SecurityUtil;
import com.allinpay.ets.client.StringUtil;
import com.ym.b2b.commons.controller.BaseController;
import com.ym.b2b.order.dao.EmSOrderDao;
import com.ym.b2b.order.sqlbean.EmSOrder;
import com.ym.b2b.payment.service.EmSPaymentService;
import com.ym.b2b.user.dao.EmCUserDAO;
import com.zc.commons.base.Result;
import com.zc.commons.spring.SpringContextHolder;

@Controller
@RequestMapping("/allinPay")
public class ManageAllinPayController extends BaseController {

    private InquiryParam      inquiryParamBean = SpringContextHolder.getBean("inquiryParamBean");

    @Autowired
    private EmSOrderDao       emSOrderDao;

    @Autowired
    private EmCUserDAO        emCUserDAO;

    @Autowired
    private EmSPaymentService emSPaymentService;

    @RequestMapping("inquiryAllinPayInfo.do")
    @ResponseBody
    public Result inquiryAllinPayInfo(EmSOrder emSOrder, HttpServletRequest req) {
        Result ret = new Result();
        try {
            // 组装需要塞入的订单信息
            EmSOrder s = emSOrderDao.searchOrderDetail(emSOrder);

            InquiryParam inquiryParam = new InquiryParam();
            inquiryParam = inquiryParamBean;
            System.out.println("单例调试：" + inquiryParam.getSignMsg());

            inquiryParam.setOrderNo(s.getOrderCode());
            SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddhhmmss");
            if (s.getFeeDate() != null) {
                inquiryParam.setOrderDatetime(sf.format(s.getCreateDate()));
            } else if (s.getCreateDate() != null) {
                inquiryParam.setOrderDatetime(sf.format(s.getCreateDate()));
            } else {
                inquiryParam.setOrderDatetime(sf.format(s.getCreateDate()));
            }

            inquiryParam.setQueryDatetime(sf.format(new Date()));
            inquiryParam.setSignMsg(getSignMsg(inquiryParam, req));

            // 提交查询请求
            String serverUrl = inquiryParam.getServerUrl();
            String key = inquiryParam.getKey();
            String merchantId = inquiryParam.getMerchantId();
            String version = inquiryParam.getVersion();
            String signType = inquiryParam.getSignType();
            String orderNo = inquiryParam.getOrderNo();
            String orderDatetime = inquiryParam.getOrderDatetime();
            String queryDatetime = inquiryParam.getQueryDatetime();
            String signMsg = inquiryParam.getSignMsg();

            boolean isSuccess = false;
            String resultMsg = "";
            Map<String, String> result = new HashMap<String, String>();

            String status = s.getStatus().toString();
            String strStatus = s.getStrStatus();
            String feeDate = s.getFeeDate();
            Double feeAmount = s.getFeeAmount();
            String listenUrl = serverUrl;
            Integer orderType = s.getOrderType();
            HttpClient httpclient = new HttpClient();
            PostMethod postmethod = new PostMethod(listenUrl);
            NameValuePair[] date = { new NameValuePair("merchantId", merchantId),
                    new NameValuePair("version", version), new NameValuePair("signType", signType),
                    new NameValuePair("orderNo", orderNo), new NameValuePair("orderDatetime", orderDatetime),
                    new NameValuePair("queryDatetime", queryDatetime), new NameValuePair("signMsg", signMsg) };
            postmethod.setRequestBody(date);
            int responseCode = httpclient.executeMethod(postmethod);
            System.out.println("responseCode=" + responseCode);

            if (responseCode == HttpURLConnection.HTTP_OK) {
                String strResponse = postmethod.getResponseBodyAsString();

                // 解析查询返回结果
                strResponse = URLDecoder.decode(strResponse);
                // Map<String, String> result = new HashMap<String, String>();
                String[] parameters = strResponse.split("&");
                for (int i = 0; i < parameters.length; i++) {
                    String msg = parameters[i];
                    int index = msg.indexOf('=');
                    if (index > 0) {
                        String name = msg.substring(0, index);
                        String value = msg.substring(index + 1);
                        result.put(name, value);
                    }
                }
                System.out.println("查询结果：" + result);

                // 查询结果会以Server方式通知商户(同支付返回)；
                // 若无法取得Server通知结果，可以通过解析查询返回结果，更新订单状态(参考如下).
                if (null != result.get("ERRORCODE")) {
                    // 未查询到订单
                    System.out.println("ERRORCODE=" + result.get("ERRORCODE"));
                    System.out.println("ERRORMSG=" + result.get("ERRORMSG"));
                    resultMsg = result.get("ERRORMSG");

                } else {
                    // 查询到订单
                    String payResult = result.get("payResult");
                    if (payResult.equals("1")) {
                        System.out.println("订单付款成功！");

                        // 支付成功，验证签名
                        PaymentResult paymentResult = new PaymentResult();
                        paymentResult.setMerchantId(result.get("merchantId"));
                        paymentResult.setVersion(result.get("version"));
                        paymentResult.setLanguage(result.get("language"));
                        paymentResult.setSignType(result.get("signType"));
                        paymentResult.setPayType(result.get("payType"));
                        paymentResult.setIssuerId(result.get("issuerId"));
                        paymentResult.setPaymentOrderId(result.get("paymentOrderId"));
                        paymentResult.setOrderNo(result.get("orderNo"));
                        paymentResult.setOrderDatetime(result.get("orderDatetime"));
                        paymentResult.setOrderAmount(result.get("orderAmount"));
                        paymentResult.setPayAmount(result.get("payAmount"));
                        paymentResult.setPayDatetime(result.get("payDatetime"));
                        paymentResult.setExt1(result.get("ext1"));
                        paymentResult.setExt2(result.get("ext2"));
                        paymentResult.setPayResult(result.get("payResult"));
                        paymentResult.setErrorCode(result.get("errorCode"));
                        paymentResult.setReturnDatetime(result.get("returnDatetime"));
                        paymentResult.setKey(key);
                        paymentResult.setSignMsg(result.get("signMsg"));
                        paymentResult.setCertPath(req.getRealPath("/cer/") + "/TLCert-test.cer");

                        boolean verifyResult = paymentResult.verify();

                        if (verifyResult) {
                            System.out.println("验签成功！商户更新订单状态。");
                            resultMsg = "订单支付成功，验签成功！商户更新订单状态。";
                            if (s.getStatus().intValue() != 20) {
                                isSuccess = true;
                                status = "20";
                                strStatus = "已支付";
                                orderType = 1;
                                feeDate = result.get("payDatetime");
                                feeAmount = Double.parseDouble(result.get("payAmount")) / 100;
                            }
                        } else {
                            System.out.println("验签失败！");
                            resultMsg = "订单支付成功，验签失败！";
                        }

                    } else {
                        System.out.println("订单尚未付款！");
                        resultMsg = "订单尚未付款！";
                    }

                }

            } else {
                System.out.println("网络不通,无法查询！");
                resultMsg = "网络不通,无法查询！";
            }
            result.put("status", status);
            result.put("strStatus", strStatus);
            ret.putData("feeDate", feeDate);
            ret.putData("feeAmount", feeAmount);
            ret.putData("resultMsg", resultMsg);
            ret.putData("isSuccess", isSuccess);
            ret.putData("orderType", orderType);
            ret.putData("result", result);

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            ret.setCodeResult(Result.CODE_100, e.getMessage());
        }

        return ret;

    }

    private String getSignMsg(InquiryParam inquiry, HttpServletRequest req) {

        String signSrc = "";
        String serverUrl = inquiry.getServerUrl();
        String key = inquiry.getKey();
        String merchantId = inquiry.getMerchantId();
        String version = inquiry.getVersion();
        String signType = inquiry.getSignType();
        String orderNo = inquiry.getOrderNo();
        String orderDatetime = inquiry.getOrderDatetime();
        String queryDatetime = inquiry.getQueryDatetime();

        StringBuffer bufSignSrc = new StringBuffer();
        StringUtil.appendSignPara(bufSignSrc, "merchantId", merchantId);
        StringUtil.appendSignPara(bufSignSrc, "version", version);
        StringUtil.appendSignPara(bufSignSrc, "signType", signType);
        StringUtil.appendSignPara(bufSignSrc, "orderNo", orderNo);
        StringUtil.appendSignPara(bufSignSrc, "orderDatetime", orderDatetime);
        StringUtil.appendSignPara(bufSignSrc, "queryDatetime", queryDatetime);
        StringUtil.appendLastSignPara(bufSignSrc, "key", key);
        signSrc = bufSignSrc.toString();
        String sign = "";
        sign = SecurityUtil.MD5Encode(bufSignSrc.toString());
        return sign;
    }

}
